#include "adc_driver.h"
#include "esp_log.h"

static const char *TAG = "ADC_DRIVER";

// 静态全局变量
static TaskHandle_t adc_task_handle = NULL;
static SemaphoreHandle_t adc_mutex;
static esp_adc_cal_characteristics_t adc_chars;
static float current_zero_point = ACS712_ZERO_POINT;
static float current_sensitivity = ACS712_SENSITIVITY;
static adc_measurement_t latest_measurement;

// 私有函数声明
static uint32_t read_avg_adc(adc1_channel_t channel, uint8_t samples);
static float convert_to_voltage(uint32_t raw_value);
static float convert_to_current(uint32_t raw_value);
static bool check_current_valid(float current);
static void adc_task(void *arg);

void adc_init(void)
{
    // 初始化电源控制GPIO
    gpio_reset_pin(POWER_ENABLE_GPIO);
    gpio_set_direction(POWER_ENABLE_GPIO, GPIO_MODE_OUTPUT);
    adc_power_ctrl(false); // 默认关闭电源
    // ADC基础配置
    adc1_config_width(ADC_WIDTH);
    adc1_config_channel_atten(VOLTAGE_ADC_CHANNEL, ADC_ATTEN);
    adc1_config_channel_atten(CURRENT_ADC_CHANNEL, ADC_ATTEN);

    // 校准初始化
    esp_adc_cal_characterize(ADC_UNIT_1, ADC_ATTEN,
                             ADC_WIDTH, 1100, &adc_chars);

    // 验证ADC能否读取
    uint32_t test_val = adc1_get_raw(VOLTAGE_ADC_CHANNEL);
    ESP_LOGI(TAG, "Test read CH%d: %lu", VOLTAGE_ADC_CHANNEL, test_val);
    // 创建互斥锁
    adc_mutex = xSemaphoreCreateMutex();
    assert(adc_mutex != NULL);

    ESP_LOGI(TAG, "ADC initialized (Ch9:48V, Ch6:Current)");
}

// 新增电源控制函数
void adc_power_ctrl(bool enable)
{
    gpio_set_level(POWER_ENABLE_GPIO, enable ? POWER_ENABLE_LEVEL : !POWER_ENABLE_LEVEL);
    ESP_LOGI(TAG, "5V Power %s", enable ? "ENABLED" : "DISABLED");
    vTaskDelay(pdMS_TO_TICKS(10)); // 确保电源稳定
}

bool adc_get_measurement(adc_measurement_t *meas, TickType_t timeout)
{
    if (xSemaphoreTake(adc_mutex, timeout))
    {
        *meas = latest_measurement;
        xSemaphoreGive(adc_mutex);
        return true;
    }
    return false;
}

void adc_calibrate_current(float zero_point, float sensitivity)
{
    current_zero_point = zero_point;
    current_sensitivity = sensitivity;
    ESP_LOGI(TAG, "Current calibrated: Zero=%.3fV, Sens=%.4fV/A",
             zero_point, sensitivity);
}

static uint32_t read_avg_adc(adc1_channel_t channel, uint8_t samples)
{
    uint32_t sum = 0;
    for (int i = 0; i < samples; i++)
    {
        sum += adc1_get_raw(channel);

        vTaskDelay(pdMS_TO_TICKS(1)); // 防止ADC连续采样冲突
    }
    return sum / samples;
}

static float convert_to_voltage(uint32_t raw_value)
{
    float mv = esp_adc_cal_raw_to_voltage(raw_value, &adc_chars);
    return (mv / 1000.0f) * VOLTAGE_DIVIDER_RATIO;
}

static float convert_to_current(uint32_t raw_value)
{
    float voltage = esp_adc_cal_raw_to_voltage(raw_value, &adc_chars) / 1000.0f;
    return (voltage - current_zero_point) / current_sensitivity;
}

static bool check_current_valid(float current)
{
    return !isnan(current) && (fabsf(current) <= CURRENT_MAX_RANGE);
}

static void adc_task(void *arg)
{
    ESP_LOGI(TAG, "ADC task entering main loop");

    const TickType_t interval = pdMS_TO_TICKS(100); // 10Hz采样率
    TickType_t last_wake = xTaskGetTickCount();
    uint32_t loop_count = 0;

    while (1)
    {

        // 1. 采集数据（带互斥锁保护）
        adc_measurement_t new_meas;
        if (xSemaphoreTake(adc_mutex, pdMS_TO_TICKS(50)) == pdTRUE)
        {
            new_meas.raw_voltage = read_avg_adc(VOLTAGE_ADC_CHANNEL, SAMPLE_SIZE);
            new_meas.raw_current = read_avg_adc(CURRENT_ADC_CHANNEL, SAMPLE_SIZE);
            xSemaphoreGive(adc_mutex);

            // 2. 数据转换
            new_meas.bus_voltage = convert_to_voltage(new_meas.raw_voltage);
            new_meas.current = convert_to_current(new_meas.raw_current);
        }
        else
        {
            ESP_LOGW(TAG, "Mutex timeout at loop %lu", loop_count);
        }

        // 4. 调试输出（每10次循环输出一次）
        if (loop_count++ % 10 == 0)
        {
            ESP_LOGI(TAG, "Sample[%lu] V=%.2fV, I=%.2fA (Raw: V=%ld, I=%ld)",
                     loop_count,
                     new_meas.bus_voltage,
                     new_meas.current,
                     new_meas.raw_voltage,
                     new_meas.raw_current);
        }

        // 5. 确保严格周期执行
        vTaskDelayUntil(&last_wake, interval);
    }
}

void adc_start_collection_task(void)
{
    if (adc_task_handle == NULL)
    {
        adc_power_ctrl(true);          // 先开启电源
        vTaskDelay(pdMS_TO_TICKS(50)); // 等待电源稳定
        // 提高任务优先级（原为5，建议改为8-10）
        xTaskCreate(adc_task, "adc_collect", 4096, NULL, 5, &adc_task_handle);
        ESP_LOGI(TAG, "ADC task started with 5V power enabled");
        // 添加启动延迟确保任务运行
        vTaskDelay(pdMS_TO_TICKS(100));

        // 强制打印任务状态
        if (adc_task_handle != NULL)
        {
            ESP_LOGI(TAG, "Task created, core:%d",
                     xTaskGetAffinity(adc_task_handle));
        }
        else
        {
            ESP_LOGE(TAG, "Task creation failed!");
        }
    }
}

void adc_stop_collection_task(void)
{
    if (adc_task_handle != NULL)
    {
        vTaskDelete(adc_task_handle);
        adc_task_handle = NULL;
        adc_power_ctrl(false); // 关闭电源
        ESP_LOGI(TAG, "ADC task stopped, 5V power disabled");
        ESP_LOGI(TAG, "ADC collection task stopped");
    }
}
